/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.nanosn.coffeemaker.application.commands.generate.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.Id;
import org.apache.commons.lang.StringUtils;

/**
 *
 * @author selkhateeb
 */
public class EntityClass {

    Class<?> entity;
    ClassName name;
    EntityColumn idColumn;
    List<EntityColumn> columns;
    Map<String, Object> freeMarkerMap;
    Set<String> imports;

    public EntityClass(Class<?> entity) throws NoSuchMethodException {
        this.entity = entity;
        this.name = new ClassName(entity.getSimpleName());
        initColumns();
    }

    private void initColumns() throws NoSuchMethodException {

        System.out.println("initColumns: " + this.entity + " Fields:" + this.entity.getDeclaredFields().length);
        this.columns = new ArrayList<EntityColumn>();
        this.imports = new HashSet<String>();

        for (Field field : this.entity.getDeclaredFields()) {
            System.out.println("Id annotated: " + field.isAnnotationPresent(Id.class));

            if (!field.getType().isPrimitive()) {
                this.imports.add(field.getType().getName());
            }
            if (field.isAnnotationPresent(Id.class)) {
                //this is the id column
                this.idColumn = new EntityColumn(field, getGetterFor(field), getSetterFor(field));
            }
            else {
                this.columns.add(new EntityColumn(field, getGetterFor(field), getSetterFor(field)));
            }
        }


    }

    private Method getGetterFor(Field field) throws NoSuchMethodException {
        String methodName = "get" + StringUtils.capitalize(field.getName());

        return this.entity.getMethod(methodName, new Class[]{});
    }

    private Method getSetterFor(Field field) throws NoSuchMethodException {
        String methodName = "set" + StringUtils.capitalize(field.getName());

        return this.entity.getMethod(methodName, new Class[]{field.getType()});
    }

    private void initFreeMarkerMap() {
        freeMarkerMap = new HashMap<String, Object>();
        freeMarkerMap.put("imports", this.imports);
        freeMarkerMap.put("name", name);

        freeMarkerMap.put("idColumn", idColumn.getAsMap());

        ArrayList<Map<String, Object>> columnsArray = new ArrayList<Map<String, Object>>();
        for (EntityColumn entityColumn : columns) {
            columnsArray.add(entityColumn.getAsMap());
        }

        freeMarkerMap.put("columns", columnsArray);
    }

    public Map<String, Object> getAsMap() {
        if (freeMarkerMap == null) {
            initFreeMarkerMap();
        }
        return freeMarkerMap;
    }
}
